﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace FisheryPlatform.Search.Core.Analysis
{
    /// <summary>
    /// FWLDictionary, which is also a Fiexed Word Length Dictionary.
    /// But do not use Lexicon Index.
    /// </summary>
    /// <author>gwd, 2006-6-6</author>
    public class FWLDictionary : Dictionary
    {
        private Hashtable _lexMap = null;      // store lexicons
        private Hashtable _charFreqMap = null;     // store chinese character frequece

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="name"></param>
        /// <param name="fullPath"></param>
        /// <param name="minWordLength"></param>
        /// <param name="maxWordLength"></param>
        public FWLDictionary(string name, string fullPath, int minWordLength, int maxWordLength)
            : base(name, fullPath, minWordLength, maxWordLength)
        {
            _lexMap = new Hashtable();
            _charFreqMap = new Hashtable();
        }
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="name"></param>
        /// <param name="fullPath"></param>
        public FWLDictionary(string name, string fullPath)
            : this(name, fullPath, 2, 8)
        { }

        /// <summary>
        /// Load lexicons from the dictionary path.
        /// </summary>
        protected internal override void LoadDictionary()
        {
            LoadCharFreq();
            for (int i = this.MinWordLength; i <= this.MaxWordLength; i++)
            {
                Lexicon lexicon = new FWLLexicon(this, i);
                lexicon.LoadLexiconIndex();
                lexicon.LoadLexicon();
                _lexMap[i] = lexicon;
            }
        }


        #region Character Freq

        /// <summary>
        /// Load character frequence from CHARFREQ.DAT file.
        /// </summary>
        protected internal virtual void LoadCharFreq()
        {
            string filePath = this.FullPath + System.IO.Path.DirectorySeparatorChar.ToString() + "CHARFREQ.DAT";
            System.IO.FileInfo charFreqFile = new System.IO.FileInfo(filePath);

            if (!charFreqFile.Exists)
            {
                System.Console.Out.WriteLine("Character Frequence Data file not exists");
                return;
            }

            try
            {
                System.IO.StreamReader reader = null;
                try
                {
                    reader = new System.IO.StreamReader(filePath, MMSupport.GetEncoding());
                    string entry;
                    while ((entry = reader.ReadLine()) != null)
                    {
                        this.ParseCharFreqEntry(entry);
                    }
                }
                finally
                {
                    if (reader != null) reader.Close();
                }
            }
            catch (System.IO.FileNotFoundException e)
            {
                System.Console.Out.WriteLine("Cannot find Character Frequence File: " + filePath);
                System.Console.Error.WriteLine(e.ToString());
            }
            catch (System.IO.IOException e)
            {
                System.Console.Out.WriteLine("Cannot read Character Frequence File: " + filePath);
                System.Console.Error.WriteLine(e.ToString());
            }
        }

        /// <summary>
        /// parse a character frequence.
        /// </summary>
        /// <param name="line">character+frequence</param>
        protected internal virtual void ParseCharFreqEntry(string line)
        {
            string character = line.Substring(0, 1);
            string freq = line.Substring(1).Trim();

            _charFreqMap[character] = long.Parse(freq);
        }

        /// <summary>
        /// Fetch a "character" frequence from the memory Hashtable.
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        public override long GetCharacterFreq(string character)
        {
            if (_charFreqMap[character] == null)
                return 0;
            else
                return (long)_charFreqMap[character];
        }

        #endregion

        /// <summary>
        /// See Dicionary.Lookup
        /// </summary>
        /// <param name="entry"></param>
        /// <returns></returns>
        public override bool Lookup(string entry)
        {
            int nLength = entry.Length;
            Lexicon lexicon = (Lexicon)_lexMap[nLength];
            if (lexicon == null) return false;

            if (lexicon.GetEntry(entry) != null)
                return true;
            else
                return false;
        }

        /// <summary>
        /// The same as this.Lookup.
        /// </summary>
        /// <param name="entry"></param>
        /// <returns></returns>
        public override bool MaybeHaveEntry(string entry)
        {
            return this.Lookup(entry);
        }

    }
}
